/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or ( at your option ) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "commonheaders.h"
#include "m_icq.h"

namespace NServices 
{
	namespace SendSMS 
	{

		enum EPhoneType {
			PHONE_NONE,
			PHONE_NORMAL,
			PHONE_SMS
		};

		static HANDLE nhMenuItem			= NULL;
		static HANDLE nhExtraIcon[2]	= { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };

		/**
		 * This function reads the contact's phone number from database and returns its type.
		 *
		 * @param	hContact	- handle to contact to read email from
		 * @param	dbv				- retrieves the email address string
		 *
		 * @retval	PHONE_SMS:		The phone supports sms, so is a cellular
		 * @retval	PHONE_NORMAL: The phone is a normal phone
		 * @retval	PHONE_NONE:		The contact does not provide any phone number
		 **/
		static INT Get( HANDLE hContact, DBVARIANT *pdbv )
		{
			// ignore owner
			if( hContact != NULL ) 
			{
				LPCSTR szProto = DB::Contact::Proto( hContact );
				if( szProto != NULL ) 
				{
					// contact has cellular and can receive sms
					if(
						!DB::Setting::GetAStringEx( hContact, USERINFO, szProto, SET_CONTACT_CELLULAR, pdbv ) ||
						!DB::Setting::GetAStringEx( hContact, USERINFO, szProto, SET_CONTACT_COMPANY_CELLULAR, pdbv )
						)
					{
						return PHONE_SMS;
					}

					if(
						!DB::Setting::GetAStringEx( hContact, USERINFO, szProto, SET_CONTACT_PHONE, pdbv ) ||
						!DB::Setting::GetAStringEx( hContact, USERINFO, szProto, SET_CONTACT_COMPANY_PHONE, pdbv )
						)
					{
						return PHONE_NORMAL;
					}

					// check for private phone numbers
					if(
						!DB::Setting::GetAString( hContact, USERINFO, "MyPhone0", pdbv ) ||
						!DB::Setting::GetAString( hContact, USERINFO, "MyCompanyPhone0", pdbv )
						)
					{
						if( pdbv->pszVal ) 
						{
							if( !strstr( pdbv->pszVal, " SMS") )
							{
								return PHONE_SMS;
							}
							return PHONE_NORMAL;
						}
					}
				}
			}
			return PHONE_NONE;
		}

		/***********************************************************************************************************
		 * Event Handler functions
		 ***********************************************************************************************************/

		static INT OnCListRebuildIcons( WPARAM wParam, LPARAM lParam )
		{
			nhExtraIcon[0] = ( HANDLE )CallService( MS_CLIST_EXTRA_ADD_ICON, ( WPARAM )NIcoLib::GetIcon( ICO_BTN_PHONE ), 0 );
			nhExtraIcon[1] = ( HANDLE )CallService( MS_CLIST_EXTRA_ADD_ICON, ( WPARAM )NIcoLib::GetIcon( ICO_BTN_CELLULAR ), 0 );
			return 0;
		}

		/**
		 * Notification handler for clist extra icons to be applied for a contact.
		 *
		 * @param wParam	- handle to the contact whose extra icon is to apply
		 * @param	lParam	- not used
		 **/
		static INT OnCListApplyIcons( WPARAM wParam, LPARAM lParam )
		{
			DBVARIANT dbv;
			IconExtraColumn iec;

			iec.cbSize = sizeof( IconExtraColumn );
			// to support the ugly shitfuckin' clist_nicer++
			iec.ColumnType = myGlobals.IsCListNicer ? 2 : EXTRA_ICON_SMS;
			switch( Get( ( HANDLE )wParam, &dbv ) ) 
			{
				case PHONE_NORMAL:
					{
						iec.hImage = nhExtraIcon[0];
						DB::Variant::Free( &dbv );
						break;
					}
				case PHONE_SMS:
					{
						iec.hImage = nhExtraIcon[1];
						DB::Variant::Free( &dbv );
						break;
					}
				default:
					{
						iec.hImage = INVALID_HANDLE_VALUE;
					}
			}
			CallService( MS_CLIST_EXTRA_SET_ICON, wParam, ( LPARAM )&iec );
			return 0;
		}

		/**
		 * Notification handler for changed contact settings
		 *
		 * @param	wParam	-	( HANDLE )hContact
		 * @param	lParam	-	( DBCONTACTWRITESETTING* )pdbcws
		 **/
		static INT OnContactSettingChanged( WPARAM wParam, LPARAM lParam )
		{
			if( wParam )
			{
				DBCONTACTWRITESETTING* pdbcws = ( DBCONTACTWRITESETTING* )lParam;

				if( pdbcws != NULL)
				{
					if(
						!mir_strcmp( pdbcws->szSetting, SET_CONTACT_PHONE ) ||
						!mir_strcmp( pdbcws->szSetting, SET_CONTACT_CELLULAR ) ||
						!mir_strncmp( pdbcws->szSetting, "MyPhone0", 8 )
						)
					{
						OnCListApplyIcons( wParam, 0 );
					}
				}
			}
			return 0;
		}

		/***********************************************************************************************************
		 * public Module Interface functions
		 ***********************************************************************************************************/

		/**
		 * Force all icons to be reloaded.
		 *
		 * @param	wParam	- handle to the contact whose extra icon is to apply
		 * @param lParam	- not used
		 **/
		VOID ApplyCListIcons()
		{
			HANDLE hContact;

			//walk through all the contacts stored in the DB
			for( hContact = DB::Contact::FindFirst();	hContact != NULL;	hContact = DB::Contact::FindNext( hContact ) )
			{
				OnCListApplyIcons( ( WPARAM ) hContact, 0 );
			}
		}

		/**
		 * Enable or disable the replacement of clist extra icons.
		 *
		 * @param	bEnable		- determines whether icons are enabled or not
		 * @param bUpdateDB	- if true the database setting is updated, too.
		 **/
		VOID EnableExtraIcons( BOOLEAN bEnable, BOOLEAN bUpdateDB ) 
		{
			if( myGlobals.HaveCListExtraIcons )
			{
				static HANDLE	hChangedHook			= NULL;
				static HANDLE	hApplyIconHook		= NULL;
				static HANDLE	hRebuildIconsHook = NULL;

				if( bUpdateDB )
				{
					DB::Setting::WriteByte( SET_CLIST_EXTRAICON_PHONE, bEnable );
				}

				if( bEnable ) 
				{
					// hook events
					if( hChangedHook == NULL ) 
					{
						hChangedHook = HookEvent( ME_DB_CONTACT_SETTINGCHANGED, OnContactSettingChanged );
					}
					if( hApplyIconHook == NULL ) 
					{
						hApplyIconHook = HookEvent( ME_CLIST_EXTRA_IMAGE_APPLY, OnCListApplyIcons );
					}
					if( hRebuildIconsHook == NULL ) 
					{
						hRebuildIconsHook = HookEvent( ME_CLIST_EXTRA_LIST_REBUILD, OnCListRebuildIcons );
						OnCListRebuildIcons( 0, 0 );
					}
				}
				else 
				{
					UnhookEvent( hChangedHook ); 
					hChangedHook = NULL;
					
					UnhookEvent( hApplyIconHook ); 
					hApplyIconHook = NULL;
					
					UnhookEvent( hRebuildIconsHook ); 
					hRebuildIconsHook = NULL;
				}
				ApplyCListIcons();
			}
		}

		/**
		 * This function initially loads the module uppon startup.
		 **/
		VOID LoadModule()
		{
			EnableExtraIcons( DB::Setting::GetByte( SET_CLIST_EXTRAICON_PHONE, DEFVAL_CLIST_EXTRAICON_PHONE ), FALSE );
		}
	
	} /* namespace NSendSMS */

} /* namespace NServices */

